<template>
  <div class="table-container">
    <div class="table-toolbar">
      <!--顶部左侧区域-->
      <div class="flex items-center table-toolbar-left">
        <template v-if="title">
          <div class="table-toolbar-left-title">
            {{ title }}
            <n-tooltip trigger="hover" v-if="titleTooltip">
              <template #trigger>
                <n-icon size="18" class="ml-1 text-gray-400 cursor-pointer">
                  <QuestionCircleOutlined />
                </n-icon>
              </template>
              {{ titleTooltip }}
            </n-tooltip>
          </div>
        </template>
        <slot name="tableTitle"></slot>
      </div>

      <div class="flex items-center table-toolbar-right">
        <!--顶部右侧区域-->
        <slot name="toolbar"></slot>

        <!--斑马纹-->
        <n-tooltip trigger="hover">
          <template #trigger>
            <div class="mr-2 table-toolbar-right-icon">
              <n-switch v-model:value="tableProps.striped" />
            </div>
          </template>
          <span>表格斑马纹</span>
        </n-tooltip>
        <n-divider vertical />

        <!--刷新-->
        <n-tooltip trigger="hover">
          <template #trigger>
            <div class="table-toolbar-right-icon" @click="reload">
              <n-icon size="18">
                <ReloadOutlined />
              </n-icon>
            </div>
          </template>
          <span>刷新</span>
        </n-tooltip>

        <!--密度-->
        <n-tooltip trigger="hover">
          <template #trigger>
            <div class="table-toolbar-right-icon">
              <n-dropdown
                @select="densitySelect"
                trigger="click"
                :options="densityOptions"
                :value="tableProps.size"
              >
                <n-icon size="18">
                  <ColumnHeightOutlined />
                </n-icon>
              </n-dropdown>
            </div>
          </template>
          <span>密度</span>
        </n-tooltip>

        <!--表格设置单独抽离成组件-->
        <ColumnSettings :table-columns="tableColumns" @change="onChangeColSet" />
        <!--全屏-->
        <n-tooltip trigger="hover">
          <template #trigger>
            <div class="table-toolbar-right-icon" @click="fullScreen">
              <n-icon size="18">
                <component :is="isFullScreen?'FullscreenExitOutlined':'FullscreenOutlined'"></component>
              </n-icon>
            </div>
          </template>
          <span>全屏</span>
        </n-tooltip>
      </div>
    </div>
    <div class="s-table">
      <n-data-table
        ref="tableElRef"
        v-bind="tableProps"
      >
        <template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
          <slot :name="item" v-bind="data"></slot>
        </template>
      </n-data-table>
    </div>
  </div>
</template>
<script lang="ts">
import {defineComponent,ref,unref,watchEffect,computed,toRaw,onMounted,onUnmounted} from 'vue';
import type {DataTableProps,DataTableColumn} from 'naive-ui';
import {dataTableProps} from 'naive-ui/es/data-table/src/interface.js'
import { ReloadOutlined, ColumnHeightOutlined, QuestionCircleOutlined, FullscreenOutlined, FullscreenExitOutlined } from '@vicons/antd';
import ColumnSettings from './ColumnSettings.vue';
import { useDebounceFn } from '@vueuse/core';

export default defineComponent({
  name: 'BaseTable',
  inheritAttrs: false,
  components: {
      ReloadOutlined,
      ColumnHeightOutlined,
      QuestionCircleOutlined,
      FullscreenOutlined,
      FullscreenExitOutlined,
      ColumnSettings,
  },
  props:{
    ...dataTableProps,
    title:{
      type:String,
      default:''
    },
    titleTooltip:{
      type:String,
      default:''
    }
  },
  emits:['reload','fullScreen'],
  setup(props, {emit,expose }){
    const tableElRef = ref<ComponentRef>(null);
    const tableProps = ref<DataTableProps>({});
    const tableColumns = ref<Array<DataTableColumn>>([]);
    const densityOptions = [
      {
        type: 'menu',
        label: '紧凑',
        key: 'small',
      },
      {
        type: 'menu',
        label: '默认',
        key: 'medium',
      },
      {
        type: 'menu',
        label: '宽松',
        key: 'large',
      },
    ];
    //计算数据表高度
    const computeTableHeight = ():number|string =>{
        const table = unref(tableElRef);
        if (!table) return 150;//默认高度150
        if(typeof props.maxHeight==='string')return props.maxHeight//如果外部传入的表格最大高度值，是字符串的话直接使用输出
        const tableEl: any = table?.$el;//获取数据表的dom对象
        const headEl = tableEl.querySelector('.n-data-table-thead');//找到表头dom对象
        const headElBottom =  headEl.getBoundingClientRect().bottom;//获取底边在浏览器可视区域位置
        const clientHeight = window.document.documentElement.clientHeight;//获取可视窗口高度
        
        const paddingH = 16;
        const marginH = 22;
        let paginationH = 2;
        
        const paginationEl = tableEl.querySelector('.n-data-table__pagination') as HTMLElement;//找到分页dom对象
        if (paginationEl) {//判断是否有分页dom
          const offsetHeight = paginationEl.offsetHeight;
          paginationH += offsetHeight || 0;
        } else {
          paginationH += 28;
        }
        let height:number|string =  (clientHeight-headElBottom) -  ( paddingH + paginationH + marginH);
        
        const maxHeight = props.maxHeight;
        //如果外部传入的表格最大高度值，是数字对比计算出的结果取大值，如果没有传入此值的话默认150后再比较
        height =  (maxHeight||150) < height ? height : maxHeight||150;
        return height;
    }
    //设置数据表高度
    const setTableHeight = ():void => {
      tableProps.value.maxHeight = computeTableHeight();
    }
    //窗口尺寸变化处理函数（延迟处理）
    const resizeHandle = useDebounceFn(()=>{
      setTableHeight();
    },200);
    watchEffect(()=>{
      for(const key in dataTableProps){
        tableProps.value[key] = props[key];
      }
      setTableHeight();
      tableColumns.value = toRaw(unref(props.columns)) as Array<DataTableColumn>;
    });
    onMounted(()=>{
      window.addEventListener('resize',resizeHandle);
    });
    onUnmounted(()=>{
      window.removeEventListener('resize', resizeHandle);
    })
    const isFullScreen = computed(()=>!!document.fullscreenElement);
    //刷新
    const reload = ()=>{
      emit('reload');
    }
    //密度选择
    const densitySelect = (value)=>{
      tableProps.value.size = value;
    }
    //表列设置变化
    const onChangeColSet = (value)=>{
      tableProps.value.columns = value;
    }
    //全屏
    const fullScreen = ()=>{
      emit('fullScreen');
    }
    //暴露setTableHeight方法
    expose({setTableHeight});
    return {
      tableElRef,
      tableProps,
      tableColumns,
      densitySelect,
      reload,
      densityOptions,
      onChangeColSet,
      isFullScreen,
      fullScreen
    }
  }
});
</script>
<style lang="less" scoped>
.table-container{
  .table-toolbar {
      display: flex;
      justify-content: space-between;
      padding: 0 0 16px 0;

      &-left {
        display: flex;
        align-items: center;
        justify-content: flex-start;
        flex: 1;

        &-title {
          display: flex;
          align-items: center;
          justify-content: flex-start;
          font-size: 16px;
          font-weight: 600;
        }
      }

      &-right {
        display: flex;
        justify-content: flex-end;
        flex: 1;

        &-icon {
          margin-left: 12px;
          font-size: 16px;
          cursor: pointer;
          color: var(--text-color);

          :hover {
            color: #1890ff;
          }
        }
      }
    }
}
  
</style>
